// var声明可以在包含它的函数，模块，命名空间或全局作用域内部任何位置被访问

// setTimeout在若干毫秒后执行一个函数，并且是在for循环结束后。 for循环结束后，i的值为10。
for (var i = 0; i < 10; i++) {
    // setTimeout(function() { console.log(i); }, 100 * i);
}

for (var i = 0; i < 10; i++) {
    // capture the current state of 'i'
    // by invoking a function with its current value
    (function(i) {
        // setTimeout(function() { console.log(i); }, 100 * i);
    })(i);
}

//块作用域变量在包含它们的块或for循环之外是不能访问的。
function f(input: boolean) {
    let a = 100;

    if (input) {
        // Still okay to reference 'a'
        let b = a + 1;
        return b;
    }

    // return b; //会报错
    return a;
}

// 在catch语句里声明的变量也具有同样的作用域规则。
try {
    throw "oh no!";
}
catch (e) {
    console.log("Oh well.");
}
// console.log(e);//也会报错

// a++; // 它们不能在被声明之前读或写
let a;

function foo() {
    // okay to capture 'a'
    console.log("123456");
    return c + 5;
}

// 不能在'a'被声明前调用'foo'
// 运行时应该抛出错误
foo();
let c = 10;

function f2(xs) {
    // let xs = 100;//报错
    return xs = 100; // error: interferes with parameter declaration
}

// 并不是说块级作用域变量不能在函数作用域内声明。
function fs(condition, x) {
    if (condition) {
        let x = 100;
        return x;
    }

    return x;
}
// fs(false, 0); // returns 0
// fs(true, 0);  // returns 100


function sumMatrix(matrix: number[][]) {
    let sum = 0;
    for (let i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (let i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

for (let i = 0; i < 10 ; i++) {
    // setTimeout(function() {console.log(i); }, 100 * i);
}

//它们引用的值是不可变的。
const numLivesForCat = 9;


let input = [1,2];
let [first,second] = input;
[first, second] = [second, first];
function firsts([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}
firsts([first,second]);



// 你可以在数组里使用...语法创建剩余变量：
let [stare, ...rest] = [1, 2, 3, 4];
// console.log(first); // outputs 1
// console.log(rest); // outputs [ 2, 3, 4 ]

let [first2] = [1, 2, 3, 4];//忽略你不关心的尾随元素
// console.log(first2);//1

let [, seconds, , fourth] = [1, 2, 3, 4];
// console.log(fourth);//2,4

// 对象解构
let o = {an:"sss",b:36,c:'2125'};
let {an,b}:{an: string, b: number} = o;//如果你想指定它的类型
// console.log(o.an);

let {...passthrough } = o;
let total = passthrough.b + passthrough.c.length;


function keepWholeObject(wholeObject: { a: string, b?: number }) {
    let { a, b = 1001 } = wholeObject;//给b默认值
}


let first1 = [1, 2];
let second1 = [3, 4];
let bothPlus = [0, ...first1, ...second1, 5];
// 这会令bothPlus的值为[0, 1, 2, 3, 4, 5]。


// 你还可以展开对象：
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { ...defaults, food: "rich" };





